﻿<!DOCTYPE html>
<html class="theme theme-white">
<head>
<meta charset="utf-8">
<title>Java I/O面试题</title>
<link href="https://www.zybuluo.com/static/assets/template-theme-white.css" rel="stylesheet" media="screen">
<style type="text/css">

#wmd-preview h1  {
    color: #0077bb; /* 将标题改为蓝色 */
}</style>
</head>
<body class="theme theme-white">
<div id="wmd-preview" class="wmd-preview wmd-preview-full-reader"><div class="md-section-divider"></div><div class="md-section-divider"></div><h1 data-anchor-id="dke7" id="java-io面试题">Java I/O面试题</h1><p data-anchor-id="a372"><code>I/O</code> <code>Java面试题</code></p><hr><div class="md-section-divider"></div><h3 data-anchor-id="f8ub" id="流的概念和作用">流的概念和作用</h3><p data-anchor-id="owzq">流是一种有顺序的，有起点和终点的字节集合，是对数据传输的总成或抽象。即数据在两设备之间的传输称之为流，流的本质是数据传输，根据数据传输的特性讲流抽象为各种类，方便更直观的进行数据操作。</p><div class="md-section-divider"></div><h3 data-anchor-id="ccb3" id="io流的分类">IO流的分类</h3><p data-anchor-id="ur88">根据数据处理类的不同分为：字符流和字节流。</p><p data-anchor-id="wi4g">根据数据流向不同分为：输入流和输出流。</p><div class="md-section-divider"></div><h3 data-anchor-id="1q8v" id="字符流和字节流">字符流和字节流</h3><p data-anchor-id="9s54">字符流的由来：因为数据编码的不同，而有了对字符进行高效操作的流对象，其本质就是基于字节流读取时，去查了指定的码表。字符流和字节流的区别：</p><p data-anchor-id="uod8">（1）读写单位不同：字节流一字节（8bit）为单位，字符流以字符为单位，根据码表映射字符，一次可能读多个字节。</p><p data-anchor-id="gfpj">（2）处理对象不同：字节流能处理所有类型的数据（例如图片，avi），而字符流只能处理字符类型的数据。</p><p data-anchor-id="w5ix">（3）字节流操作的时候本身是不会用到缓冲区的，是对文件本身的直接操作。而字符流在操作的时候是会用到缓冲区的，通过缓冲区来操作文件。</p><p data-anchor-id="kqpl">结论：优先使用字节流，首先因为在硬盘上所有的文件都是以字节的形式进行传输或保存的，包括图片等内容。但是字符流只是在内存中才会形成，所以在开发中字节流使用广泛。</p><div class="md-section-divider"></div><h2 data-anchor-id="h29b" id="输入流和输出流">输入流和输出流</h2><p data-anchor-id="94ct">对输入流只能进行读操作，对输出流只能进行写操作。程序中根据数据传输的不同特性使用不同的流。</p><div class="md-section-divider"></div><h2 data-anchor-id="7xei" id="输入字节流inputstream">输入字节流InputStream</h2><p data-anchor-id="cm2y">InputStream是所有输入字节流的父类，它是一个抽象类。</p><p data-anchor-id="b84r">ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流，它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。PipedInputStream 是从与其它线程共用的管道中读取数据。</p><p data-anchor-id="p55c">ObjectInputStream 和所有FilterInputStream的子类都是装饰流（装饰器模式的主角）。意思是FileInputStream类可以通过一个String路径名创建一个对象，FileInputStream(String name)。而DataInputStream必须装饰一个类才能返回一个对象，DataInputStream(InputStream in)。</p><p data-anchor-id="7z6m">ByteArrayInputStream:</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="kscu"><ol class="linenums"><li class="L0"><code class="language-java"><span class="com">/**  </span></code></li><li class="L1"><code class="language-java"><span class="com"> * 使用内存操作流将一个大写字母转化为小写字母  </span></code></li><li class="L2"><code class="language-java"><span class="com"> * */</span><span class="pln">  </span></code></li><li class="L3"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.*;</span><span class="pln">  </span></code></li><li class="L4"><code class="language-java"><span class="kwd">class</span><span class="pln"> hello</span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L5"><code class="language-java"><span class="pln">   </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">String</span><span class="pun">[]</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">throws</span><span class="pln"> </span><span class="typ">IOException</span><span class="pln"> </span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L6"><code class="language-java"><span class="pln">       </span><span class="typ">String</span><span class="pln"> str</span><span class="pun">=</span><span class="str">"Homiss"</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L7"><code class="language-java"><span class="pln">       </span><span class="typ">ByteArrayInputStream</span><span class="pln"> input</span><span class="pun">=</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ByteArrayInputStream</span><span class="pun">(</span><span class="pln">str</span><span class="pun">.</span><span class="pln">getBytes</span><span class="pun">());</span><span class="pln">  </span></code></li><li class="L8"><code class="language-java"><span class="pln">       </span><span class="typ">ByteArrayOutputStream</span><span class="pln"> output</span><span class="pun">=</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ByteArrayOutputStream</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L9"><code class="language-java"><span class="pln">       </span><span class="kwd">int</span><span class="pln"> temp</span><span class="pun">=</span><span class="lit">0</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L0"><code class="language-java"><span class="pln">       </span><span class="kwd">while</span><span class="pun">((</span><span class="pln">temp</span><span class="pun">=</span><span class="pln">input</span><span class="pun">.</span><span class="pln">read</span><span class="pun">())!=-</span><span class="lit">1</span><span class="pun">){</span><span class="pln">  </span></code></li><li class="L1"><code class="language-java"><span class="pln">           </span><span class="kwd">char</span><span class="pln"> ch</span><span class="pun">=(</span><span class="kwd">char</span><span class="pun">)</span><span class="pln">temp</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L2"><code class="language-java"><span class="pln">           output</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="typ">Character</span><span class="pun">.</span><span class="pln">toLowerCase</span><span class="pun">(</span><span class="pln">ch</span><span class="pun">));</span><span class="pln">  </span></code></li><li class="L3"><code class="language-java"><span class="pln">       </span><span class="pun">}</span><span class="pln">  </span></code></li><li class="L4"><code class="language-java"><span class="pln">       </span><span class="typ">String</span><span class="pln"> outStr</span><span class="pun">=</span><span class="pln">output</span><span class="pun">.</span><span class="pln">toString</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L5"><code class="language-java"><span class="pln">       input</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L6"><code class="language-java"><span class="pln">       output</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L7"><code class="language-java"><span class="pln">       </span><span class="typ">System</span><span class="pun">.</span><span class="pln">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="pln">outStr</span><span class="pun">);</span><span class="pln">  </span></code></li><li class="L8"><code class="language-java"><span class="pln">    </span><span class="pun">}</span><span class="pln">  </span></code></li><li class="L9"><code class="language-java"><span class="pun">}</span><span class="pln">  </span></code></li></ol></pre><p data-anchor-id="m8dn">字节流FileInputStream读取文件：</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="hqoj"><ol class="linenums"><li class="L0"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">File</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">FileInputStream</span><span class="pun">;</span></code></li><li class="L2"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">IOException</span><span class="pun">;</span></code></li><li class="L3"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">InputStream</span><span class="pun">;</span></code></li><li class="L4"><code class="language-java"></code></li><li class="L5"><code class="language-java"><span class="com">/**</span></code></li><li class="L6"><code class="language-java"><span class="com"> * @author Homiss</span></code></li><li class="L7"><code class="language-java"><span class="com"> * 逐字节读取文件内容</span></code></li><li class="L8"><code class="language-java"><span class="com"> */</span></code></li><li class="L9"><code class="language-java"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">IOFileInputStream</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L0"><code class="language-java"></code></li><li class="L1"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">String</span><span class="pun">...</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">throws</span><span class="pln"> </span><span class="typ">IOException</span><span class="pun">{</span></code></li><li class="L2"><code class="language-java"><span class="pln">        </span><span class="typ">String</span><span class="pln"> path </span><span class="pun">=</span><span class="pln"> </span><span class="str">"F:"</span><span class="pun">+</span><span class="typ">File</span><span class="pun">.</span><span class="pln">separator</span><span class="pun">+</span><span class="str">"test.txt"</span><span class="pun">;</span></code></li><li class="L3"><code class="language-java"><span class="pln">        </span><span class="typ">File</span><span class="pln"> file </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="pln">path</span><span class="pun">);</span></code></li><li class="L4"><code class="language-java"><span class="pln">        </span><span class="typ">InputStream</span><span class="pln"> in </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FileInputStream</span><span class="pun">(</span><span class="pln">file</span><span class="pun">);</span></code></li><li class="L5"><code class="language-java"></code></li><li class="L6"><code class="language-java"><span class="pln">        </span><span class="kwd">byte</span><span class="pun">[]</span><span class="pln"> b </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="kwd">byte</span><span class="pun">[</span><span class="lit">1024</span><span class="pun">];</span></code></li><li class="L7"><code class="language-java"><span class="pln">        </span><span class="kwd">int</span><span class="pln"> temp </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span></code></li><li class="L8"><code class="language-java"><span class="pln">        </span><span class="kwd">int</span><span class="pln"> count </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span></code></li><li class="L9"><code class="language-java"><span class="pln">        </span><span class="kwd">while</span><span class="pun">((</span><span class="pln">temp </span><span class="pun">=</span><span class="pln"> in</span><span class="pun">.</span><span class="pln">read</span><span class="pun">())</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="pun">-</span><span class="lit">1</span><span class="pun">){</span></code></li><li class="L0"><code class="language-java"><span class="pln">            b</span><span class="pun">[</span><span class="pln">count</span><span class="pun">++]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">byte</span><span class="pun">)</span><span class="pln">temp</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"><span class="pln">        </span><span class="pun">}</span></code></li><li class="L2"><code class="language-java"><span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">String</span><span class="pun">(</span><span class="pln">b</span><span class="pun">));</span></code></li><li class="L3"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L4"><code class="language-java"><span class="pun">}</span></code></li></ol></pre><p data-anchor-id="fzi9">FileOutputStream添加内容：</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="nc0w"><ol class="linenums"><li class="L0"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">File</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">FileOutputStream</span><span class="pun">;</span></code></li><li class="L2"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">IOException</span><span class="pun">;</span></code></li><li class="L3"><code class="language-java"></code></li><li class="L4"><code class="language-java"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">IOFileOutputStream</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L5"><code class="language-java"></code></li><li class="L6"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">String</span><span class="pun">...</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">throws</span><span class="pln"> </span><span class="typ">IOException</span><span class="pun">{</span></code></li><li class="L7"><code class="language-java"><span class="pln">        </span><span class="typ">String</span><span class="pln"> path </span><span class="pun">=</span><span class="pln"> </span><span class="str">"f:"</span><span class="pun">+</span><span class="typ">File</span><span class="pun">.</span><span class="pln">separator</span><span class="pun">+</span><span class="str">"test.txt"</span><span class="pun">;</span></code></li><li class="L8"><code class="language-java"><span class="pln">        </span><span class="com">//true表示在文件末尾追加内容</span></code></li><li class="L9"><code class="language-java"><span class="pln">        </span><span class="typ">FileOutputStream</span><span class="pln"> fout </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FileOutputStream</span><span class="pun">(</span><span class="pln">path</span><span class="pun">,</span><span class="kwd">true</span><span class="pun">);</span></code></li><li class="L0"><code class="language-java"><span class="pln">        </span><span class="typ">String</span><span class="pln"> str </span><span class="pun">=</span><span class="pln"> </span><span class="str">"\r\n半兽人"</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"></code></li><li class="L2"><code class="language-java"><span class="pln">        fout</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">str</span><span class="pun">.</span><span class="pln">getBytes</span><span class="pun">());</span></code></li><li class="L3"><code class="language-java"><span class="pln">        fout</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span></code></li><li class="L4"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L5"><code class="language-java"><span class="pun">}</span></code></li></ol></pre><p data-anchor-id="ds4d">PushBackInputStream回退流操作：</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="owfk"><ol class="linenums"><li class="L0"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">ByteArrayInputStream</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">IOException</span><span class="pun">;</span></code></li><li class="L2"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">PushbackInputStream</span><span class="pun">;</span></code></li><li class="L3"><code class="language-java"></code></li><li class="L4"><code class="language-java"><span class="com">/**</span></code></li><li class="L5"><code class="language-java"><span class="com"> * @author Homiss</span></code></li><li class="L6"><code class="language-java"><span class="com"> * PushbackInputStream</span></code></li><li class="L7"><code class="language-java"><span class="com"> */</span></code></li><li class="L8"><code class="language-java"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">IOPushbackInputStream</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L9"><code class="language-java"></code></li><li class="L0"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">String</span><span class="pun">...</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">throws</span><span class="pln"> </span><span class="typ">IOException</span><span class="pun">{</span></code></li><li class="L1"><code class="language-java"><span class="pln">        </span><span class="typ">String</span><span class="pln"> str </span><span class="pun">=</span><span class="pln"> </span><span class="str">"hello , this is my Blog!"</span><span class="pun">;</span></code></li><li class="L2"><code class="language-java"><span class="pln">        </span><span class="typ">ByteArrayInputStream</span><span class="pln"> in </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ByteArrayInputStream</span><span class="pun">(</span><span class="pln">str</span><span class="pun">.</span><span class="pln">getBytes</span><span class="pun">());</span></code></li><li class="L3"><code class="language-java"><span class="pln">        </span><span class="typ">PushbackInputStream</span><span class="pln"> pis </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">PushbackInputStream</span><span class="pun">(</span><span class="pln">in</span><span class="pun">);</span></code></li><li class="L4"><code class="language-java"></code></li><li class="L5"><code class="language-java"><span class="pln">        </span><span class="kwd">int</span><span class="pln"> temp </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span></code></li><li class="L6"><code class="language-java"><span class="pln">        </span><span class="kwd">while</span><span class="pun">((</span><span class="pln">temp </span><span class="pun">=</span><span class="pln"> pis</span><span class="pun">.</span><span class="pln">read</span><span class="pun">())</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="pun">-</span><span class="lit">1</span><span class="pun">){</span></code></li><li class="L7"><code class="language-java"><span class="pln">            </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">temp </span><span class="pun">==</span><span class="pln"> </span><span class="str">','</span><span class="pun">){</span></code></li><li class="L8"><code class="language-java"><span class="pln">                pis</span><span class="pun">.</span><span class="pln">unread</span><span class="pun">(</span><span class="pln">temp</span><span class="pun">);</span></code></li><li class="L9"><code class="language-java"><span class="pln">                temp </span><span class="pun">=</span><span class="pln"> pis</span><span class="pun">.</span><span class="pln">read</span><span class="pun">();</span></code></li><li class="L0"><code class="language-java"><span class="pln">                </span><span class="typ">System</span><span class="pun">.</span><span class="pln">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">((</span><span class="kwd">char</span><span class="pun">)</span><span class="pln">temp</span><span class="pun">);</span></code></li><li class="L1"><code class="language-java"><span class="pln">            </span><span class="pun">}</span><span class="kwd">else</span><span class="pun">{</span></code></li><li class="L2"><code class="language-java"><span class="pln">                </span><span class="typ">System</span><span class="pun">.</span><span class="pln">out</span><span class="pun">.</span><span class="pln">print</span><span class="pun">((</span><span class="kwd">char</span><span class="pun">)</span><span class="pln">temp</span><span class="pun">);</span></code></li><li class="L3"><code class="language-java"><span class="pln">            </span><span class="pun">}</span></code></li><li class="L4"><code class="language-java"><span class="pln">        </span><span class="pun">}</span></code></li><li class="L5"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L6"><code class="language-java"><span class="pun">}</span></code></li></ol></pre><p data-anchor-id="amfr">PipedInputStream管道流操作：</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="ckdg"><ol class="linenums"><li class="L0"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">IOException</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">PipedInputStream</span><span class="pun">;</span></code></li><li class="L2"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">PipedOutputStream</span><span class="pun">;</span></code></li><li class="L3"><code class="language-java"></code></li><li class="L4"><code class="language-java"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">IOPipedOutputStream</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L5"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">String</span><span class="pun">...</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">throws</span><span class="pln"> </span><span class="typ">IOException</span><span class="pun">{</span></code></li><li class="L6"><code class="language-java"></code></li><li class="L7"><code class="language-java"><span class="pln">        </span><span class="typ">Send</span><span class="pln"> send</span><span class="pun">=</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Send</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L8"><code class="language-java"><span class="pln">        </span><span class="typ">Recive</span><span class="pln"> recive</span><span class="pun">=</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Recive</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L9"><code class="language-java"><span class="pln">        </span><span class="kwd">try</span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L0"><code class="language-java"><span class="pln">           send</span><span class="pun">.</span><span class="pln">getOut</span><span class="pun">().</span><span class="pln">connect</span><span class="pun">(</span><span class="pln">recive</span><span class="pun">.</span><span class="pln">getInput</span><span class="pun">());</span><span class="pln">  </span></code></li><li class="L1"><code class="language-java"><span class="pln">        </span><span class="pun">}</span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Exception</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L2"><code class="language-java"><span class="pln">           e</span><span class="pun">.</span><span class="pln">printStackTrace</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L3"><code class="language-java"><span class="pln">        </span><span class="pun">}</span><span class="pln">  </span></code></li><li class="L4"><code class="language-java"><span class="pln">        </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Thread</span><span class="pun">(</span><span class="pln">recive</span><span class="pun">).</span><span class="pln">start</span><span class="pun">();</span></code></li><li class="L5"><code class="language-java"><span class="pln">        </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Thread</span><span class="pun">(</span><span class="pln">send</span><span class="pun">).</span><span class="pln">start</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L6"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L7"><code class="language-java"><span class="pun">}</span></code></li><li class="L8"><code class="language-java"></code></li><li class="L9"><code class="language-java"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Send</span><span class="pln"> </span><span class="kwd">implements</span><span class="pln"> </span><span class="typ">Runnable</span><span class="pun">{</span></code></li><li class="L0"><code class="language-java"></code></li><li class="L1"><code class="language-java"><span class="pln">    </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">PipedOutputStream</span><span class="pln"> out </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">;</span></code></li><li class="L2"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">Send</span><span class="pun">(){</span></code></li><li class="L3"><code class="language-java"><span class="pln">        out </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">PipedOutputStream</span><span class="pun">();</span></code></li><li class="L4"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L5"><code class="language-java"></code></li><li class="L6"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">PipedOutputStream</span><span class="pln"> getOut</span><span class="pun">(){</span></code></li><li class="L7"><code class="language-java"><span class="pln">        </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">out</span><span class="pun">;</span></code></li><li class="L8"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L9"><code class="language-java"></code></li><li class="L0"><code class="language-java"><span class="pln">    </span><span class="lit">@Override</span></code></li><li class="L1"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> run</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L2"><code class="language-java"><span class="pln">        </span><span class="com">// TODO Auto-generated method stub</span></code></li><li class="L3"><code class="language-java"><span class="pln">        </span><span class="typ">String</span><span class="pln"> message</span><span class="pun">=</span><span class="str">"hello , Homiss"</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L4"><code class="language-java"><span class="pln">        </span><span class="kwd">try</span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L5"><code class="language-java"><span class="pln">           out</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">message</span><span class="pun">.</span><span class="pln">getBytes</span><span class="pun">());</span><span class="pln">  </span></code></li><li class="L6"><code class="language-java"><span class="pln">        </span><span class="pun">}</span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Exception</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L7"><code class="language-java"><span class="pln">           e</span><span class="pun">.</span><span class="pln">printStackTrace</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L8"><code class="language-java"><span class="pln">        </span><span class="pun">}</span><span class="kwd">try</span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L9"><code class="language-java"><span class="pln">            out</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span></code></li><li class="L0"><code class="language-java"><span class="pln">        </span><span class="pun">}</span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Exception</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L1"><code class="language-java"><span class="pln">           e</span><span class="pun">.</span><span class="pln">printStackTrace</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L2"><code class="language-java"><span class="pln">       </span><span class="pun">}</span></code></li><li class="L3"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L4"><code class="language-java"><span class="pun">}</span></code></li><li class="L5"><code class="language-java"></code></li><li class="L6"><code class="language-java"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Recive</span><span class="pln"> </span><span class="kwd">implements</span><span class="pln"> </span><span class="typ">Runnable</span><span class="pun">{</span></code></li><li class="L7"><code class="language-java"></code></li><li class="L8"><code class="language-java"><span class="pln">    </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">PipedInputStream</span><span class="pln"> input </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">;</span></code></li><li class="L9"><code class="language-java"></code></li><li class="L0"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">Recive</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L1"><code class="language-java"><span class="pln">        input </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">PipedInputStream</span><span class="pun">();</span></code></li><li class="L2"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L3"><code class="language-java"></code></li><li class="L4"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">PipedInputStream</span><span class="pln"> getInput</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L5"><code class="language-java"><span class="pln">        </span><span class="kwd">return</span><span class="pln"> input</span><span class="pun">;</span></code></li><li class="L6"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L7"><code class="language-java"></code></li><li class="L8"><code class="language-java"><span class="pln">    </span><span class="lit">@Override</span></code></li><li class="L9"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> run</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L0"><code class="language-java"><span class="pln">        </span><span class="com">// TODO Auto-generated method stub</span></code></li><li class="L1"><code class="language-java"><span class="pln">        </span><span class="kwd">byte</span><span class="pun">[]</span><span class="pln"> b </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="kwd">byte</span><span class="pun">[</span><span class="lit">1024</span><span class="pun">];</span></code></li><li class="L2"><code class="language-java"><span class="pln">        </span><span class="kwd">int</span><span class="pln"> len </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span></code></li><li class="L3"><code class="language-java"><span class="pln">        </span><span class="kwd">try</span><span class="pun">{</span></code></li><li class="L4"><code class="language-java"><span class="pln">            len </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">input</span><span class="pun">.</span><span class="pln">read</span><span class="pun">(</span><span class="pln">b</span><span class="pun">);</span></code></li><li class="L5"><code class="language-java"><span class="pln">        </span><span class="pun">}</span><span class="kwd">catch</span><span class="pun">(</span><span class="typ">Exception</span><span class="pln"> e</span><span class="pun">){</span></code></li><li class="L6"><code class="language-java"><span class="pln">            e</span><span class="pun">.</span><span class="pln">printStackTrace</span><span class="pun">();</span></code></li><li class="L7"><code class="language-java"><span class="pln">        </span><span class="pun">}</span></code></li><li class="L8"><code class="language-java"><span class="pln">        </span><span class="typ">System</span><span class="pun">.</span><span class="pln">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"接受到的内容为:"</span><span class="pun">+(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">String</span><span class="pun">(</span><span class="pln">b</span><span class="pun">,</span><span class="lit">0</span><span class="pun">,</span><span class="pln">len</span><span class="pun">)));</span></code></li><li class="L9"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L0"><code class="language-java"><span class="pun">}</span></code></li></ol></pre><p data-anchor-id="0o0n">SequenceInputStream:将两个文本文件合并为另外一个文本文件</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="00xa"><ol class="linenums"><li class="L0"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">File</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">FileInputStream</span><span class="pun">;</span></code></li><li class="L2"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">FileOutputStream</span><span class="pun">;</span></code></li><li class="L3"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">IOException</span><span class="pun">;</span></code></li><li class="L4"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">InputStream</span><span class="pun">;</span></code></li><li class="L5"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">OutputStream</span><span class="pun">;</span></code></li><li class="L6"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">SequenceInputStream</span><span class="pun">;</span></code></li><li class="L7"><code class="language-java"></code></li><li class="L8"><code class="language-java"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">SequenceInputStreamDemo</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L9"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">String</span><span class="pun">...</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">throws</span><span class="pln"> </span><span class="typ">IOException</span><span class="pun">{</span></code></li><li class="L0"><code class="language-java"><span class="pln">        </span><span class="typ">File</span><span class="pln"> f1 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="str">"f:"</span><span class="pun">+</span><span class="typ">File</span><span class="pun">.</span><span class="pln">separator</span><span class="pun">+</span><span class="str">"test.txt"</span><span class="pun">);</span></code></li><li class="L1"><code class="language-java"><span class="pln">        </span><span class="typ">File</span><span class="pln"> f2 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="str">"f:"</span><span class="pun">+</span><span class="typ">File</span><span class="pun">.</span><span class="pln">separator</span><span class="pun">+</span><span class="str">"homiss.txt"</span><span class="pun">);</span></code></li><li class="L2"><code class="language-java"><span class="pln">        </span><span class="typ">File</span><span class="pln"> f3 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="str">"f:"</span><span class="pun">+</span><span class="typ">File</span><span class="pun">.</span><span class="pln">separator</span><span class="pun">+</span><span class="str">"my.txt"</span><span class="pun">);</span></code></li><li class="L3"><code class="language-java"></code></li><li class="L4"><code class="language-java"><span class="pln">        </span><span class="typ">InputStream</span><span class="pln"> in1 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FileInputStream</span><span class="pun">(</span><span class="pln">f1</span><span class="pun">);</span></code></li><li class="L5"><code class="language-java"><span class="pln">        </span><span class="typ">InputStream</span><span class="pln"> in2 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FileInputStream</span><span class="pun">(</span><span class="pln">f2</span><span class="pun">);</span></code></li><li class="L6"><code class="language-java"><span class="pln">        </span><span class="typ">OutputStream</span><span class="pln"> out </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FileOutputStream</span><span class="pun">(</span><span class="pln">f3</span><span class="pun">);</span></code></li><li class="L7"><code class="language-java"></code></li><li class="L8"><code class="language-java"><span class="pln">        </span><span class="com">//合并流</span></code></li><li class="L9"><code class="language-java"><span class="pln">        </span><span class="typ">SequenceInputStream</span><span class="pln"> sis </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">SequenceInputStream</span><span class="pun">(</span><span class="pln">in1</span><span class="pun">,</span><span class="pln">in2</span><span class="pun">);</span></code></li><li class="L0"><code class="language-java"><span class="pln">        </span><span class="kwd">int</span><span class="pln"> temp </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"><span class="pln">        </span><span class="kwd">while</span><span class="pun">((</span><span class="pln">temp </span><span class="pun">=</span><span class="pln"> sis</span><span class="pun">.</span><span class="pln">read</span><span class="pun">())</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="pun">-</span><span class="lit">1</span><span class="pun">){</span></code></li><li class="L2"><code class="language-java"><span class="pln">            out</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">temp</span><span class="pun">);</span></code></li><li class="L3"><code class="language-java"><span class="pln">        </span><span class="pun">}</span></code></li><li class="L4"><code class="language-java"><span class="pln">        in1</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span></code></li><li class="L5"><code class="language-java"><span class="pln">        in2</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span></code></li><li class="L6"><code class="language-java"><span class="pln">        out</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span></code></li><li class="L7"><code class="language-java"><span class="pln">        sis</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span></code></li><li class="L8"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L9"><code class="language-java"><span class="pun">}</span></code></li></ol></pre><p data-anchor-id="67qj">PrintStream:也可以认为是一个辅助工具。主要可以向其他输出流，或者FileInputStream 写入数据，本身内部实现还是带缓冲的。</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="1zcf"><ol class="linenums"><li class="L0"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">File</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">FileOutputStream</span><span class="pun">;</span></code></li><li class="L2"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">IOException</span><span class="pun">;</span></code></li><li class="L3"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">PrintStream</span><span class="pun">;</span></code></li><li class="L4"><code class="language-java"></code></li><li class="L5"><code class="language-java"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">PrintStreamDemo</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L6"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">String</span><span class="pun">...</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">throws</span><span class="pln"> </span><span class="typ">IOException</span><span class="pun">{</span></code></li><li class="L7"><code class="language-java"><span class="pln">        </span><span class="typ">File</span><span class="pln"> f </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="str">"f:"</span><span class="pun">+</span><span class="typ">File</span><span class="pun">.</span><span class="pln">separator</span><span class="pun">+</span><span class="str">"test.txt"</span><span class="pun">);</span></code></li><li class="L8"><code class="language-java"><span class="pln">        </span><span class="typ">PrintStream</span><span class="pln"> print </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">PrintStream</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FileOutputStream</span><span class="pun">(</span><span class="pln">f</span><span class="pun">));</span></code></li><li class="L9"><code class="language-java"></code></li><li class="L0"><code class="language-java"><span class="pln">        </span><span class="typ">String</span><span class="pln"> name </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Homiss"</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"><span class="pln">        </span><span class="kwd">int</span><span class="pln"> age </span><span class="pun">=</span><span class="pln"> </span><span class="lit">21</span><span class="pun">;</span></code></li><li class="L2"><code class="language-java"><span class="pln">        print</span><span class="pun">.</span><span class="pln">printf</span><span class="pun">(</span><span class="str">"姓名：%s . 年龄：%d ."</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">age</span><span class="pun">);</span></code></li><li class="L3"><code class="language-java"><span class="pln">        print</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span></code></li><li class="L4"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L5"><code class="language-java"><span class="pun">}</span></code></li></ol></pre><p data-anchor-id="22ql">ZipOutputStream:</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="14fx"><ol class="linenums"><li class="L0"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">File</span><span class="pun">;</span></code></li><li class="L1"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">FileInputStream</span><span class="pun">;</span></code></li><li class="L2"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">FileOutputStream</span><span class="pun">;</span></code></li><li class="L3"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">IOException</span><span class="pun">;</span></code></li><li class="L4"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">InputStream</span><span class="pun">;</span></code></li><li class="L5"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">util</span><span class="pun">.</span><span class="pln">zip</span><span class="pun">.</span><span class="typ">ZipEntry</span><span class="pun">;</span></code></li><li class="L6"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">util</span><span class="pun">.</span><span class="pln">zip</span><span class="pun">.</span><span class="typ">ZipOutputStream</span><span class="pun">;</span></code></li><li class="L7"><code class="language-java"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ZipOutputStreamDemo01</span><span class="pln"> </span><span class="pun">{</span></code></li><li class="L8"><code class="language-java"><span class="pln">    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">String</span><span class="pun">...</span><span class="pln"> args</span><span class="pun">)</span><span class="kwd">throws</span><span class="pln"> </span><span class="typ">IOException</span><span class="pun">{</span></code></li><li class="L9"><code class="language-java"><span class="pln">        </span><span class="typ">File</span><span class="pln"> file </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="str">"f:"</span><span class="pun">+</span><span class="typ">File</span><span class="pun">.</span><span class="pln">separator</span><span class="pun">+</span><span class="str">"test.txt"</span><span class="pun">);</span></code></li><li class="L0"><code class="language-java"><span class="pln">        </span><span class="typ">File</span><span class="pln"> zipFile </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="str">"f:"</span><span class="pun">+</span><span class="typ">File</span><span class="pun">.</span><span class="pln">separator</span><span class="pun">+</span><span class="str">"test.zip"</span><span class="pun">);</span></code></li><li class="L1"><code class="language-java"></code></li><li class="L2"><code class="language-java"><span class="pln">        </span><span class="typ">InputStream</span><span class="pln"> in </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FileInputStream</span><span class="pun">(</span><span class="pln">file</span><span class="pun">);</span></code></li><li class="L3"><code class="language-java"><span class="pln">        </span><span class="typ">ZipOutputStream</span><span class="pln"> zipOut </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ZipOutputStream</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FileOutputStream</span><span class="pun">(</span><span class="pln">zipFile</span><span class="pun">));</span></code></li><li class="L4"><code class="language-java"></code></li><li class="L5"><code class="language-java"><span class="pln">        zipOut</span><span class="pun">.</span><span class="pln">putNextEntry</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ZipEntry</span><span class="pun">(</span><span class="pln">file</span><span class="pun">.</span><span class="pln">getName</span><span class="pun">()));</span></code></li><li class="L6"><code class="language-java"><span class="pln">        </span><span class="com">//设置注释</span></code></li><li class="L7"><code class="language-java"><span class="pln">        zipOut</span><span class="pun">.</span><span class="pln">setComment</span><span class="pun">(</span><span class="str">"Homiss"</span><span class="pun">);</span></code></li><li class="L8"><code class="language-java"><span class="pln">        </span><span class="kwd">int</span><span class="pln"> temp </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span></code></li><li class="L9"><code class="language-java"><span class="pln">        </span><span class="kwd">while</span><span class="pun">((</span><span class="pln">temp </span><span class="pun">=</span><span class="pln"> in</span><span class="pun">.</span><span class="pln">read</span><span class="pun">())</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="pun">-</span><span class="lit">1</span><span class="pun">){</span></code></li><li class="L0"><code class="language-java"><span class="pln">            zipOut</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">temp</span><span class="pun">);</span></code></li><li class="L1"><code class="language-java"><span class="pln">        </span><span class="pun">}</span></code></li><li class="L2"><code class="language-java"><span class="pln">        in</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span></code></li><li class="L3"><code class="language-java"><span class="pln">        zipOut</span><span class="pun">.</span><span class="pln">close</span><span class="pun">();</span></code></li><li class="L4"><code class="language-java"><span class="pln">    </span><span class="pun">}</span></code></li><li class="L5"><code class="language-java"><span class="pun">}</span></code></li></ol></pre><div class="md-section-divider"></div><h3 data-anchor-id="e96v" id="字符输入流reader">字符输入流Reader</h3><p data-anchor-id="d7vj">定义和说明：</p><blockquote data-anchor-id="sfxp" class="white-blockquote">
  <p>Reader 是所有的输入字符流的父类，它是一个抽象类。</p>
</blockquote><p data-anchor-id="mijb">CharReader、StringReader是两种基本的介质流，它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据。 <br>
BufferedReader 很明显就是一个装饰器，它和其子类负责装饰其它Reader 对象。 <br>
FilterReader 是所有自定义具体装饰流的父类，其子类PushbackReader 对Reader 对象进行装饰，会增加一个行号。</p><p data-anchor-id="677a">InputStreamReader 是一个连接字节流和字符流的桥梁，它将字节流转变为字符流。FileReader可以说是一个达到此功能、常用的工具类，在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。</p><p data-anchor-id="jhpe">BufferedReader:</p><blockquote data-anchor-id="cxai" class="white-blockquote">
  <p>注意：BufferedReader只能接受字符流的缓冲区，因为每一个中文需要占据两个字节，所以需要将System.in这个字节输入流变为字符输入流，采用： <br>
  BufferedReader buf = new BufferedReader(newInputStreamReader(System.in));</p>
</blockquote><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="v5uj"><ol class="linenums"><li class="L0"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">BufferedReader</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L1"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">IOException</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L2"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">InputStreamReader</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L3"><code class="language-java"></code></li><li class="L4"><code class="language-java"><span class="com">/**  </span></code></li><li class="L5"><code class="language-java"><span class="com"> * 使用缓冲区从键盘上读入内容  </span></code></li><li class="L6"><code class="language-java"><span class="com"> * */</span><span class="pln">  </span></code></li><li class="L7"><code class="language-java"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">BufferedReaderDemo</span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L8"><code class="language-java"><span class="pln">   </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">String</span><span class="pun">[]</span><span class="pln"> args</span><span class="pun">){</span><span class="pln">  </span></code></li><li class="L9"><code class="language-java"><span class="pln">       </span><span class="typ">BufferedReader</span><span class="pln"> buf </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">BufferedReader</span><span class="pun">(</span><span class="pln">  </span></code></li><li class="L0"><code class="language-java"><span class="pln">                newInputStreamReader</span><span class="pun">(</span><span class="typ">System</span><span class="pun">.</span><span class="pln">in</span><span class="pun">));</span><span class="pln">  </span></code></li><li class="L1"><code class="language-java"><span class="pln">       </span><span class="typ">String</span><span class="pln"> str </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L2"><code class="language-java"><span class="pln">       </span><span class="typ">System</span><span class="pun">.</span><span class="pln">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"请输入内容"</span><span class="pun">);</span><span class="pln">  </span></code></li><li class="L3"><code class="language-java"><span class="pln">       </span><span class="kwd">try</span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L4"><code class="language-java"><span class="pln">           str </span><span class="pun">=</span><span class="pln"> buf</span><span class="pun">.</span><span class="pln">readLine</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L5"><code class="language-java"><span class="pln">       </span><span class="pun">}</span><span class="kwd">catch</span><span class="pun">(</span><span class="typ">IOException</span><span class="pln"> e</span><span class="pun">){</span><span class="pln">  </span></code></li><li class="L6"><code class="language-java"><span class="pln">           e</span><span class="pun">.</span><span class="pln">printStackTrace</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L7"><code class="language-java"><span class="pln">       </span><span class="pun">}</span><span class="pln">  </span></code></li><li class="L8"><code class="language-java"><span class="pln">       </span><span class="typ">System</span><span class="pun">.</span><span class="pln">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"你输入的内容是："</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> str</span><span class="pun">);</span><span class="pln">  </span></code></li><li class="L9"><code class="language-java"><span class="pln">    </span><span class="pun">}</span><span class="pln">  </span></code></li><li class="L0"><code class="language-java"><span class="pun">}</span><span class="pln">  </span></code></li></ol></pre><p data-anchor-id="znoj">Scanner类从文件中读出内容:</p><div class="md-section-divider"></div><pre class="prettyprint linenums prettyprinted" data-anchor-id="shep"><ol class="linenums"><li class="L0"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">File</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L1"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">io</span><span class="pun">.</span><span class="typ">FileNotFoundException</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L2"><code class="language-java"><span class="kwd">import</span><span class="pln"> java</span><span class="pun">.</span><span class="pln">util</span><span class="pun">.</span><span class="typ">Scanner</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L3"><code class="language-java"></code></li><li class="L4"><code class="language-java"><span class="com">/**  </span></code></li><li class="L5"><code class="language-java"><span class="com"> *Scanner的小例子，从文件中读内容  </span></code></li><li class="L6"><code class="language-java"><span class="com"> * */</span><span class="pln">  </span></code></li><li class="L7"><code class="language-java"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ScannerDemo</span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L8"><code class="language-java"><span class="pln">   </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">String</span><span class="pun">[]</span><span class="pln"> args</span><span class="pun">){</span><span class="pln">  </span></code></li><li class="L9"><code class="language-java"></code></li><li class="L0"><code class="language-java"><span class="pln">       </span><span class="typ">File</span><span class="pln"> file </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">File</span><span class="pun">(</span><span class="str">"d:"</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="typ">File</span><span class="pun">.</span><span class="pln">separator </span><span class="pun">+</span><span class="str">"hello.txt"</span><span class="pun">);</span><span class="pln">  </span></code></li><li class="L1"><code class="language-java"><span class="pln">       </span><span class="typ">Scanner</span><span class="pln"> sca </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">;</span><span class="pln">  </span></code></li><li class="L2"><code class="language-java"><span class="pln">       </span><span class="kwd">try</span><span class="pun">{</span><span class="pln">  </span></code></li><li class="L3"><code class="language-java"><span class="pln">           sca </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Scanner</span><span class="pun">(</span><span class="pln">file</span><span class="pun">);</span><span class="pln">  </span></code></li><li class="L4"><code class="language-java"><span class="pln">       </span><span class="pun">}</span><span class="kwd">catch</span><span class="pun">(</span><span class="typ">FileNotFoundException</span><span class="pln"> e</span><span class="pun">){</span><span class="pln">  </span></code></li><li class="L5"><code class="language-java"><span class="pln">           e</span><span class="pun">.</span><span class="pln">printStackTrace</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L6"><code class="language-java"><span class="pln">       </span><span class="pun">}</span><span class="pln">  </span></code></li><li class="L7"><code class="language-java"><span class="pln">       </span><span class="typ">String</span><span class="pln"> str </span><span class="pun">=</span><span class="pln"> sca</span><span class="pun">.</span><span class="pln">next</span><span class="pun">();</span><span class="pln">  </span></code></li><li class="L8"><code class="language-java"><span class="pln">       </span><span class="typ">System</span><span class="pun">.</span><span class="pln">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"从文件中读取的内容是："</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> str</span><span class="pun">);</span><span class="pln">  </span></code></li><li class="L9"><code class="language-java"><span class="pln">    </span><span class="pun">}</span><span class="pln">  </span></code></li><li class="L0"><code class="language-java"><span class="pun">}</span><span class="pln">  </span></code></li></ol></pre><div class="md-section-divider"></div><h3 data-anchor-id="ep8c" id="java-io库的两个对称性">Java I/O库的两个对称性</h3><p data-anchor-id="1kvx">Java I/O库有两个对称性，他们分别是：</p><ol data-anchor-id="9o3r">
<li>输入-输出对称：比如InputStream和OutputStream各自占据byte流的输入和输出的两个平行的等级结构的根部；而Reader和Writer各自占据Char流的输入和输出的两个平行的等级结构的根部。</li>
<li>byte-char对称：InputStream和Reader的子类分别负责byte和插入流的输入；OutputStream和Writer的子类分别负责byte和插入流的输出，它们分别形成平行的等级结构。</li>
</ol><div class="md-section-divider"></div><h3 data-anchor-id="crc7" id="java-io库的两个设计模式">Java I/O库的两个设计模式</h3><p data-anchor-id="7zix">Java I/O库的总体设计是符合装饰模式和适配器模式的。如前所述，这个库中处理流的类叫流类。</p><p data-anchor-id="ivce">装饰模式（Decorator）：在由InputStream、OutputStream、Reader和Writer代表的等级结构内部，有一些流处理器可以对另一些流处理器起到装饰作用，形成新的、具有改善了的功能的流处理器。</p><p data-anchor-id="4g49">适配器模式（Adapter）：在由InputStream、OutputStream、Reader和Writer代表的等级结构内部，有一些流处理器是对其他类型的流处理器的适配。这就是适配器的应用。</p><div class="md-section-divider"></div><h4 data-anchor-id="b01l" id="装饰模式的应用">装饰模式的应用</h4><p data-anchor-id="47cx">InputStream类型中的装饰模式：</p><p data-anchor-id="8cz3">　InputStream有七个直接的具体子类，有四个属于FilterInputStream的具体子类，如下图所示：</p><p data-anchor-id="bgnm">上图中所有的类都叫做流处理器，这个图就叫做（InputStream类型的）流处理器图。</p><p data-anchor-id="91mu">书中提到根据输入流的源的类型，可以将这些流类分成两种，即原始流类（Original Stream）和链接流处理器（Wrapper Stream）。</p><div class="md-section-divider"></div><h4 data-anchor-id="8doy" id="原始流处理器">原始流处理器</h4><p data-anchor-id="qlae">原始流处理器接收一个Byte数组对象，String对象，FileDiscriptor对象或者不同类型的流源对象，根据上面的图，原始流处理器包括以下四种：</p><blockquote data-anchor-id="cprm" class="white-blockquote">
  <ul>
  <li>ByteArrayInputStream：为多线程的通信提供缓冲区操作功能，接收一个Byte数组作为流的源。</li>
  <li>FileInputStream:建立一个与文件有关的输入流。接收一个File对象作为流的源。</li>
  <li>PipedInputStream：可以与PipedOutputStream配合使用，用于读入一个数据管道的数据，接收一个PipedOutputStream作为源。</li>
  <li>StringBufferInputStream：将一个字符串缓冲区转换为一个输入流。接收一个String对象作为流的源。（ＪＤＫ帮助文档上说明：已过时。此类未能正确地将字符转换为字节。从ＪＤＫ1.1开始，从字符串创建流的首选方法是通过StringReader类进行创建。只有字符串中每个字符的低八位可以由此类使用。）</li>
  </ul>
</blockquote><div class="md-section-divider"></div><h4 data-anchor-id="balj" id="链接流处理器">链接流处理器</h4><p data-anchor-id="dbdr">所谓链接流处理器，就是可以接收另一个流对象作为源，并对之进行功能扩展的类。InputStream类型的链接处理器包括以下几种，它们都接收另一个InputStream对象作为流源。</p><p data-anchor-id="ksa5">(1)FilterInputStream称为过滤输入流，它将另一个输入流作为流源。这个类的子类包括以下几种：</p><blockquote data-anchor-id="j0pa" class="white-blockquote">
  <ul>
  <li>BufferedInputStream：用来从硬盘将数据读入到一个内存缓冲区中，并从缓冲区提供数据。</li>
  <li>DataInputStream：提供基于多字节的读取方法，可以读取原始类型的数据。</li>
  <li>LineNumberInputStream：提供带有行计数功能的过滤输入流。</li>
  <li>PushbackInputStream：提供特殊的功能，可以将已经读取的字节“推回”到输入流中。</li>
  </ul>
</blockquote><p data-anchor-id="1b4f">(2)ObjectInputStream可以将使用ObjectInputStream串行化的原始数据类型和对象重新并行化。</p><p data-anchor-id="z03j">(3)SeqcueneInputStream可以将两个已有的输入流连接起来，形成一个输入流，从而将多个输入流排列构成一个输入流序列。</p><div class="md-section-divider"></div><h3 data-anchor-id="obf8" id="nio和bio的区别">NIO和BIO的区别</h3><ul data-anchor-id="zho7">
<li>阻塞IO：使用简单，但随之而来的问题就是会形成阻塞，需要独立线程配合，而这些线程在大多数时候都是没有进行运算的。Java的BIO使用这种方式，问题带来的问题很明显，一个Socket需要一个独立的线程，因此，会造成线程膨胀。</li>
<li>非阻塞IO：采用轮询方式，不会形成线程的阻塞。Java的NIO使用这种方式，对比BIO的优势很明显，可以使用一个线程进行所有Socket的监听（select）。大大减少了线程数。</li>
</ul><div class="md-section-divider"></div><h3 data-anchor-id="qq1g" id="linux-io模型">Linux IO模型</h3><p data-anchor-id="jajq">linux下有五种常见的IO模型，其中只有一种异步模型，其余皆为同步模型。如图： <br>
<img src="http://static.zybuluo.com/homiss/tq95mnettxwgivyukwwxpph2/image_1bk88gscilce1i75jisk9r7n92q.png" alt="image_1bk88gscilce1i75jisk9r7n92q.png-26kB" title=""></p><div class="md-section-divider"></div><h3 data-anchor-id="ndg7" id="阻塞io模型">阻塞IO模型</h3><p data-anchor-id="2ted">阻塞IO模型是最常见的IO模型了，对于所有的“慢速设备”（socket、pipe、fifo、terminal）的IO默认的方式都是阻塞的方式。阻塞就是进程放弃cpu，让给其他进程使用cpu。进程阻塞最显著的表现就是进程睡眠了。阻塞的时间通常取决于数据是否到来。 <br>
这种方式使用简单，但随之而来的问题就是会形成阻塞，需要独立线程配合，而这些线程在大多数时候都是没有进行运算的。Java的BIO使用这种方式，问题带来的问题很明显，一个Socket需要一个独立的线程，因此，会造成线程膨胀。</p><p data-anchor-id="djcf"><img src="http://static.zybuluo.com/homiss/l40bwthl5c00zt1mpi632b5v/image_1bk88hgjnqr51p359avht71h3n37.png" alt="image_1bk88hgjnqr51p359avht71h3n37.png-20kB" title=""></p><div class="md-section-divider"></div><h3 data-anchor-id="zozc" id="非阻塞io模型">非阻塞IO模型</h3><p data-anchor-id="dyg1">非阻塞IO就是设置IO相关的系统调用为non-blocking，随后进行的IO操作无论有没有可用数据都会立即返回，并设置errno为EWOULDBLOCK或者EAGAIN。我们可以通过主动check的方式（polling，轮询）确保IO有效时，随之进行相关的IO操作。当然这种方式看起来就似乎不太靠谱，浪费了太多的CPU时间，用宝贵的CPU时间做轮询太不靠谱儿了。图示： <br>
<img src="http://static.zybuluo.com/homiss/7suuki09g1ymwsv3e1vlgbxa/image_1bk88i1t59b11d4dsqb112j1suf3k.png" alt="image_1bk88i1t59b11d4dsqb112j1suf3k.png-27.6kB" title=""></p><div class="md-section-divider"></div><h3 data-anchor-id="4uhp" id="多路复用">多路复用</h3><p data-anchor-id="ulij">为了解决阻塞I/O的问题,就有了I/O多路复用模型,多路复用就是用单独的线程(是内核级的, 可以认为是高效的优化的) 来统一等待所有的socket上的数据, 一当某个socket上有数据后, 就启用用户线程(可能是从线程池中取出, 而不是重新生成), copy socket data, 并且处理message.因为网络延迟的原因, 同时在处理socket data的用户线程往往比实际的socket数量要少很多. 所以实际应用中, 大部分是用线程池, 池中thread数量可随socket的高峰和低谷 而动态调整.</p><p data-anchor-id="gvt0">多路复用I/O中内核中统一﻿的wait socket data那部分可以理解成是非阻塞, 也可以理解成阻塞. 可以理解成非阻塞 是因为它不是等到socket数据全部到达再处理, 而是有了一部分数据就会调用用户线程来处理, 理解成阻塞, 是因为它和用户空间(Appliction)层的非阻塞﻿socket的不同是: socket中没有数据时, 内核还是wait(阻塞)的, 而用户空间的非阻塞﻿socket没有数据也会返回, 会造成CPU的浪费.</p><p data-anchor-id="tyz6">Linux下的select和poll 就是多路复用模式,poll相对select,没有了句柄数的限制,但他们都是在内核层通过轮询socket句柄的方式来实现的, 没有利用更底层的notify机制. 但就算是这样,相对阻塞socket也已经﻿进步了很多很多了! 毕竟用一个内核线程就解决了,阻塞socket中N多线程都在无谓地wait的局面.</p><blockquote data-anchor-id="5xj3" class="white-blockquote">
  <p>多路复用I/O﻿ 还是让用户层来copy socket data. 这个过程是将内核中的socket buffer copy到用户空间的 buffer. 这有两个问题: 一是多了一次内核空间switch到用户空间的过程, 二是用户空间层不便暴露很低层但很高效的copy方式(比如DMA), 所以如果由内核层来做这个动作, 可以更好地提高效率!</p>
</blockquote><p data-anchor-id="jv6h"><img src="http://static.zybuluo.com/homiss/yt9wrdd7grujbp1z8qmpw80y/image_1bk88j5gruddk8pv918ptd9q41.png" alt="image_1bk88j5gruddk8pv918ptd9q41.png-32.7kB" title=""></p><div class="md-section-divider"></div><h3 data-anchor-id="dqe8" id="信号驱动io模型">信号驱动IO模型</h3><p data-anchor-id="n7v6">所谓信号驱动，就是利用信号机制，安装信号SIGIO的处理函数（进行IO相关操作），通过监控文件描述符，当其就绪时，通知目标进程进行IO操作（signal handler）。 <br>
<img src="http://static.zybuluo.com/homiss/ou5borc0llzhcfggdk8uek6u/image_1bk88jplt7hjr51et81a06k524e.png" alt="image_1bk88jplt7hjr51et81a06k524e.png-23.2kB" title=""></p><div class="md-section-divider"></div><h3 data-anchor-id="xw29" id="异步io模型">异步IO模型</h3><p data-anchor-id="k5c6">由于异步IO请求只是写入了缓存，从缓存到硬盘是否成功不可知，因此异步IO相当于把一个IO拆成了两部分，一是发起请求，二是获取处理结果。因此，对应用来说增加了复杂性。但是异步IO的性能是所有很好的，而且异步的思想贯穿了IT系统放放面面。 <br>
<img src="http://static.zybuluo.com/homiss/qz90av9jfzjfrqnu0hi6d6xe/image_1bk88kd1vlm7d0f142hvcd1rln4r.png" alt="image_1bk88kd1vlm7d0f142hvcd1rln4r.png-19.6kB" title=""></p><div class="md-section-divider"></div><h3 data-anchor-id="hxur" id="epoll">epoll</h3><p data-anchor-id="2hbe">epoll是Java NIO在linux上的默认实现。相关的工具可以关注select,poll，关于三者间的区别，参见这里。在Mac上类似的实现是kqueue,Solaris上是/dev/poll。 <br>
epoll的优点</p><ul data-anchor-id="igom">
<li>支持一个进程打开大数目的socket描述符(FD)</li>
<li>IO效率不随FD数目增加而线性下降</li>
</ul><blockquote data-anchor-id="sc6q" class="white-blockquote">
  <p>传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合，不过由于网络延时，任一时间只有部分的socket是”活跃”的，但是select/poll每次调用都会线性扫描全部的集合，导致效率呈现线性下降。但是epoll不存在这个问题，它只会对”活跃”的socket进行操作—这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么，只有”活跃”的socket才会主动的去调用 callback函数，其他idle状态socket则不会，在这点上，epoll实现了一个”伪”AIO，因为这时候推动力在os内核。</p>
</blockquote><ul data-anchor-id="jv5n">
<li><p>使用mmap加速内核与用户空间的消息传递。</p></li>
<li><p>内核微调</p></li>
</ul><p data-anchor-id="ztwh">epoll有2种工作方式:LT和ET:</p><ul data-anchor-id="nvgk">
<li>LT(level triggered)是缺省的工作方式，并且同时支持block和no-block socket.在这种做法中，内核告诉你一个文件描述符是否就绪了，然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作，内核还是会继续通知你的，所以，这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表．</li>
<li>ET (edge-triggered)是高速工作方式，只支持no-block socket。在这种模式下，当描述符从未就绪变为就绪时，内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪，并且不会再为那个文件描述符发送更多的就绪通知，直到你做了某些操作导致那个文件描述符不再为就绪状态了(比如，你在发送，接收或者接收请求，或者发送接收的数据少于一定量时导致了一个EWOULDBLOCK 错误）。但是请注意，如果一直不对这个fd作IO操作(从而导致它再次变成未就绪)，内核不会发送更多的通知(only once),不过在TCP协议中，ET模式的加速效用仍需要更多的benchmark确认。</li>
</ul><div class="md-section-divider"></div><h3 data-anchor-id="5fkx" id="zero-copy">Zero Copy</h3><p data-anchor-id="dhj7">上面多次提到内核空间和用户空间的switch, 在socket read/write这么小的粒度频繁调用, 代价肯定是很大的. <br>
所以可以在网上看到Zero Copy的技术, 说到底Zero Copy的思路就是: 分析你的业务, 看看是否能避免不必要的跨空间copy,比如可以用 sendfile()函数充分利用内核可以调用DMA的优势, 直接在内核空间将文件的内容通过socket发送出去,而不必经过用户空间.显然,sendfile是有很多的前提条件的, 如果你想让文件内容作一些变换再发出去,就必须要经过用户空间的Appliation logic, 也是无法使用sendfile了.还有一种方式就是象epoll所做的,用内存映射. 据我所知，kafka速度快的一个原因就是使用了零拷贝。 <br>
关于零拷贝，可以看这篇文章</p><div class="md-section-divider"></div><h3 data-anchor-id="2685" id="c10k-问题">C10K 问题</h3><p data-anchor-id="isn2">网络服务在处理数以万计的客户端连接时,往往出现效率低下甚至完全瘫痪,这被 称为C10K问题。随着互联网的迅速发展,越来越多的网络服务开始面临 C10K 问题, 作为大型网站的开发人员有必要对C10K问题有一定的了解。 <br>
C10K问题的最大特点是:设计不够良好的程序,其性能和连接数及机器性能的关系往往是非线性的。举个例子:如果没有考虑过C10K问题,一个经典的基于select的程序能在旧服务器上很好处理1000并发的吞吐量,它在2倍性能新服务器上往往处理不了并发2000的吞吐量。 <br>
这是因为在策略不当时,大量操作的消耗和当前连接数n成线性相关。会导致单个任务的资源消耗和当前连接数的关系会是O(n)。而服务程序需要同时对数以万计的socket进行I/O处理,积累下来的资源消耗会相当可观,这显然会导致系统吞吐量不能 和机器性能匹配。为解决这个问题,必须改变对连接提供服务的策略。 <br>
更详细的资料参考：The C10K problem</p><div class="md-section-divider"></div><h3 data-anchor-id="kbbj" id="java中有几种类型的流jdk为每种类型的流提供了一些抽象类以供继承请说出他们分别是哪些类">java中有几种类型的流？JDK为每种类型的流提供了一些抽象类以供继承，请说出他们分别是哪些类？</h3><p data-anchor-id="3z6z">字节输入流：InputStream,字节输出流：OutputStream <br>
字符输入流：Reader，字符输出流：Writer</p><div class="md-section-divider"></div><h3 data-anchor-id="jxpe" id="什么是java序列化如何实现java序列化">什么是java序列化，如何实现java序列化？</h3><p data-anchor-id="mdcx">Java对象的序列化指将一个java对象写入OI流中，与此对应的是，对象的反序列化则从IO流中恢复该java对象。 <br>
如果要让某个对象支持序列化机制，则必须让它的类是可序列化的，为了让某个类是可序列化的，该类必须实现Serializable接口或Externalizable接口</p><div class="md-section-divider"></div><h3 data-anchor-id="6haz" id="解释一下javaioserializable接口面试常考">解释一下java.io.Serializable接口（面试常考）</h3><p data-anchor-id="lu1d">类通过实现 Java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。</p><div class="md-section-divider"></div><h3 data-anchor-id="anym" id="读写原始数据一般采用什么流ac">读写原始数据，一般采用什么流？（AC ）</h3><p data-anchor-id="q6su">A InputStream <br>
B DataInputStream <br>
C OutputStream <br>
D BufferedInputStream</p><div class="md-section-divider"></div><h3 data-anchor-id="yspl" id="为了提高读写性能可以采用什么流df">为了提高读写性能，可以采用什么流？（DF）</h3><p data-anchor-id="fuuh">A InputStream <br>
B DataInputStream <br>
C BufferedReader <br>
D BufferedInputStream <br>
E OutputStream <br>
F BufferedOutputStream</p><div class="md-section-divider"></div><h3 data-anchor-id="y5sw" id="对各种基本数据类型和string类型的读写采用什么流-ad">对各种基本数据类型和String类型的读写，采用什么流？（ AD）</h3><p data-anchor-id="3s6y">A DataInputStream <br>
B BufferedReader <br>
C PrintWriter <br>
D DataOutputStream <br>
E ObjectInputStream <br>
F ObjectOutputStream</p><div class="md-section-divider"></div><h3 data-anchor-id="q2h9" id="能指定字符编码的io流类型是bh">能指定字符编码的I/O流类型是：（BH ）</h3><p data-anchor-id="vr7t">A Reader <br>
B InputStreamReader <br>
C BufferedReader <br>
D Writer <br>
E PrintWriter <br>
F ObjectInputStream <br>
G ObjectOutputStream <br>
H OutputStreamWriter</p><div class="md-section-divider"></div><h3 data-anchor-id="js5o" id="file类型中定义了什么方法来判断一个文件是否存在-d">File类型中定义了什么方法来判断一个文件是否存在？（ D）</h3><p data-anchor-id="1j15">A createNewFile <br>
B renameTo <br>
C delete <br>
D exists</p><div class="md-section-divider"></div><h3 data-anchor-id="ku7m" id="file类型中定义了什么方法来创建一级目录-c">File类型中定义了什么方法来创建一级目录？（ C）</h3><p data-anchor-id="bf8k">A createNewFile <br>
B exists <br>
C mkdirs <br>
D mkdir</p><div class="md-section-divider"></div><h3 data-anchor-id="nql4" id="对文本文件操作用什么io流ad">对文本文件操作用什么I/O流？（AD ）</h3><p data-anchor-id="70j0">A FileReader <br>
B FileInputStream <br>
C RandomAccessFile <br>
D FileWriter</p><div class="md-section-divider"></div><h3 data-anchor-id="tv4e" id="在unix服务器wwwopenlabcomcn上提供了基于tcp的时间服务应用该应用使用port为13创建连接到此服务器的语句是a">在unix服务器www.openlab.com.cn上提供了基于TCP的时间服务应用，该应用使用port为13。创建连接到此服务器的语句是：（A ）</h3><p data-anchor-id="601q">A Socket s = new Socket(“www.openlab.com.cn”, 13); <br>
B Socket s = new Socket(“www.openlab.com.cn:13”); <br>
C Socket s = accept(“www.openlab.com.cn”, 13);</p><div class="md-section-divider"></div><h3 data-anchor-id="qdjo" id="创建一个tcp客户程序的顺序是dacbe">创建一个TCP客户程序的顺序是：（DACBE ）</h3><p data-anchor-id="d2e3">A 获得I/O流 <br>
B 关闭I/O流 <br>
C 对I/O流进行读写操作 <br>
D 建立socket <br>
E 关闭socket</p><div class="md-section-divider"></div><h3 data-anchor-id="w9xi" id="创建一个tcp服务程序的顺序是bcadegf">创建一个TCP服务程序的顺序是：（BCADEGF ）</h3><p data-anchor-id="tv1h">A 创建一个服务线程处理新的连接 <br>
B 创建一个服务器socket <br>
C 从服务器socket接受客户连接请求 <br>
D 在服务线程中，从socket中获得I/O流 <br>
E 对I/O流进行读写操作，完成与客户的交互 <br>
F 关闭socket <br>
G 关闭I/O流</p><div class="md-section-divider"></div><h3 data-anchor-id="dmyo" id="java-udp编程主要用到的两个类型是-bd">Java UDP编程主要用到的两个类型是：（ BD）</h3><p data-anchor-id="g6qv">A UDPSocket <br>
B DatagramSocket <br>
C UDPPacket <br>
D DatagramPacket</p><div class="md-section-divider"></div><h3 data-anchor-id="5l34" id="tcpip是一种-b">TCP/IP是一种：（ B）</h3><p data-anchor-id="unxh">A 标准  <br>
B 协议 <br>
C 语言 <br>
D 算法</p><div class="md-section-divider"></div><h3 data-anchor-id="8mvp" id="结束">结束</h3><p data-anchor-id="g6xk">文章转载自： <br>
<a href="http://blog.csdn.net/u012815721/article/details/25279613" target="_blank">http://blog.csdn.net/u012815721/article/details/25279613</a></p></div>
</body>
</html>